每天一道面试题(8)

您所在的位置:网站首页 node loop循环机制 每天一道面试题(8)

每天一道面试题(8)

2023-11-09 17:01| 来源: 网络整理| 查看: 265

说一下浏览器和node中的事件循环机制

这道题大部同学都能答上来宏任务和微任务, 不知道浏览器事件循环请移至 10 分钟理解 JS 引擎的执行机制

但是对于node中的事件循环, 很多人都没有系统的学习过, 本篇文章主要梳理一下在回答这个问题时的要点

本文将从以下两个方面进行梳理, 大家在面试的时候也可以按照这个思路进行回答

文章目录 浏览器的事件循环node中的事件循环机制node中事件循环机制的注意事项

浏览器的事件循环

由于JS是单线程的, 如果自上而下执行, 一段代码运行时间过长, 下面的代码就会堵塞. 所以js的异步机制应运而生

上面文章的参考链接中详细讲到, 浏览器的事件循环分为宏任务和微任务, 他们的划分如下

宏任务: 包括整体代码script,setTimeout,setInterval微任务: promise, 以及由promise封装而成的axios, fetch等等

看下面例子就知道了

setTimeout(function () { console.log('1') }) new Promise(function (resolve) { console.log('2') setTimeout(() => { console.log('3') }, 0) resolve() }).then(function () { console.log('4') }) console.log('5') //结果是: 2,5,4,1,3 先执行宏任务 -> 2 , 5在执行本轮的微任务: 4开启新一轮宏任务: 1 , 3

再看一个

console.log('1') // 1 同步代码:立即执行 [1] setTimeout(function () { console.log('2') new Promise(function (resolve) { console.log('4') resolve() }).then((resolve) => { console.log('5') }) }, 0) setTimeout(() => { console.log('6') }, 0) console.log('7') //1,7,2,4,5,6

这个题的知识点在于, 浏览器在执行宏任务时会优先将该宏任务中的 宏任务和微任务 都完成再去向下执行下一个宏任务, 所以该题中的2,4,5会优先于6打印出来

node中的事件循环机制

在node中, 主要是增加了两个异步事件

setImmediate: 类似于setTimeout, 是宏任务process.nextTick:是微任务,但是与普通微任务有区别,永远在微任务队列执行之前执行 console.log('1') setTimeout(() => { console.log('2') }, 0) new Promise(function (resolve, reject) { resolve() }).then(function () { console.log('3') }) //process.nextTick的优先级会比promise.then高。 process.nextTick(function () { console.log('4') }) //1, 4, 3, 2 node中事件循环机制的注意事项

但是有一个需要注意的点:就是

在node11版本之前, 如果宏任务队列中有多个任务, 就会依次执行完宏任务再去执行对应的微任务

在node11及以后的版本中, 改为一旦执行一个阶段里的一个宏任务(setTimeout,setInterval和setImmediate)就立刻执行微任务队列,这就跟浏览器端运行一致

下面看这段复杂的代码

onsole.log('1') // 1 同步代码:立即执行 [1] setTimeout(function () { console.log('2') // 3 同步代码执行执行 输出2 new Promise(function (resolve) { console.log('4') // 3 同步代码执行执行 输出4 resolve() }).then(function () { console.log('5') // 4 进入微任务队列 [3, 5] }) }) new Promise(function (resolve) { console.log('7') // 1 宏任务:立即执行 [1, 7] resolve() }).then(function () { console.log('8') // 2 进入微任务队列 [6, 8] }) setTimeout(function () { console.log('9') // 5 宏任务:立即执行 [9] new Promise(function (resolve) { console.log('11') // 5 宏任务:立即执行 [9, 11] resolve() }).then(function () { console.log('12') // 6 进入微任务队列 [10, 12] }) }) //node11及以上版本: 1 7 8 2 4 5 9 11 12 // node11以下版本 1 7 8 2 4 9 11 5 //微任务 12 //微任务

区别在于最后四位数字的打印结果, 大家自行测试



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3